﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading;


 namespace CSE445_Assignment2_ChickenSales
{
    public delegate void priceCutEvent(Int32 pr);
     public delegate void chickenSoldEvent(Int32 id, Int32 numGot);
   
    public class myApplication
    {
      
        private static Semaphore _pool;
        private static int count;
       // public static Queue buffOut;
        public static ArrayList buffOu;
      static   void Main(string[] args)
        {
            _pool = new Semaphore(0, 7);
            _pool.Release(7);
            count = cChickenFarm.NUM;
            if (count <= 0)
                count = 1;
            cChickenFarm chicken = new cChickenFarm(); 
            //buffOut = new Queue(cChickenFarm.NUM);
            buffOu = new ArrayList(count); 
            //cBuffer buffout = new cBuffer();
            //buffout.startBuffer();
            Thread farmer = new Thread(new ThreadStart(chicken.farmerFunc));
            
            cRetailer chickenstore = new cRetailer();
            cChickenFarm.priceCut += new
            priceCutEvent(chickenstore.chickenOnSale);

            cChickenFarm.chcknSold  += new
              chickenSoldEvent(chickenstore.saleDone);

            Thread[] retailers = new Thread[cChickenFarm.NUM];
            
            for (int i = 0; i < cChickenFarm.NUM ; i++)
            {   // Start N retailer threads
                retailers[i] = new Thread(new ThreadStart(chickenstore.retailerFunc));
                retailers[i].Name = (i + 1).ToString();
                retailers[i].Start();
            }

            farmer.Start();         // Start one farmer thread
            
        }
        public void getInLine(object oOrder)
        {
            string sOrder = (string)oOrder;
            _pool.WaitOne();
            //Monitor.Enter(buffOut);
            try
            {
                if (buffOu.Count < count)
                {
                    buffOu.Add(sOrder);
                    // buffOut.Enqueue(sOrder);
                }
            }
            finally
            {
                _pool.Release();
               // Monitor.Exit(buffOut);
            }
        }
        public string  getOuttaLine()
        {
            Monitor.Enter(buffOu);
            try
            {
                if (buffOu.Count > 0)
                {
                    string ret = (string)buffOu[buffOu.Count -1];
                    buffOu.RemoveAt(buffOu.Count - 1);
                    return ret;

                   //return (string)buffOut.Dequeue();
                }
            }
            finally
            {
                Monitor.Exit(buffOu);
                
            }return "";
        }

    }

}
    //public class ChickenFarm
    //{
    //    public const int NUM = 10;
    //    public int cutCount = -1;
    //    static Random rng = new Random();
    //    public static event priceCutEvent priceCut; // Define event
    //    private static Int32 chickenPrice = 10;
    //    public Int32 getPrice() { return chickenPrice; }
    //    public static void changePrice(Int32 price)
    //    {
    //        if (price < chickenPrice)
    //        { // a price cut 
    //            if (priceCut != null)  // there is at least a subscriber
    //                priceCut(price); // emit event to subscribers
    //        }
    //        chickenPrice = price;
    //    }

    //    public void farmerFunc()
    //    {
    //        for (Int32 i = 0; i < 50; i++)
    //        {
    //            Thread.Sleep(500);
    //            // Take the order from the queue of the orders;
    //            // Decide the price based on the orders
    //            Int32 p = PriceModel(); //rng.Next(5, 10); // Generate a random price
    //            // Console.WriteLine("New Price is {0}", p);
    //            ChickenFarm.changePrice(p);
    //        }
    //    }

    //    public int PriceModel()
    //    {
    //        int[] arrCost = {10,9,5,7,6,10,9,8,5,6};
    //        cutCount++;
    //        return arrCost[cutCount];

    //    }
    

        //public class Retailer
        //{
        //    public void retailerFunc()
        //    {   //for starting thread
        //        ChickenFarm chicken = new ChickenFarm();
        //        for (Int32 i = 0; i < 10; i++)
        //        {
        //            Thread.Sleep(500);
        //            Int32 p = chicken.getPrice();
        //            Console.WriteLine("Store{0} has everyday low price: ${1} each", Thread.CurrentThread.Name, p);
        //        }
        //    }
        //    public void chickenOnSale(Int32 p)
        //    {  // Event handler
        //        Console.WriteLine("Store{0} chickens are on sale: as low as ${1} each", Thread.CurrentThread.Name, p);
        //    }
        //}

    



